<template>
  <template v-if="loaded">
    <ProForm
      ref="formRef"
      :model="formState"
      :items="items"
      :disabled="readonly"
      :onValuesChange="onValuesChange"
      :formColLayout="formColLayout()"
      :requiredMark="!readonly"
      class="pro-form-modal"
      v-bind="formProps"
    >
    </ProForm>
    <FooterButtons
      :formState="formState"
      :formRef="formRef"
      v-model:readonly="readonly"
      :serviceApi="_updateMqttConfig_2"
      @refresh="refresh"
      :fastConfig="fastConfig"
    >
      <b-button v-if="!readonly" @click="handleRegister()">注 册</b-button>
      <b-button v-if="readonly" @click="historyVisible = true"
        >历史配置</b-button
      >
    </FooterButtons>

    <Modal
      title="历史配置"
      v-model:open="historyVisible"
      :width="1400"
      :mask-closable="false"
      :keyboard="false"
      :footer="null"
      centered
    >
      <ProTable
        ref="tableRef"
        :fetchListApi="_historyMqtt"
        :columns="columns"
        :height="600"
        row-key="id"
        hide-search
        :expanded-row-keys="expandedRowKeys"
        @expand="handleExpand"
      >
        <template #operation="{ record }">
          <b-button type="link" @click="MQTT_deploy(record)">下发配置</b-button>
        </template>
        <template #expandedRowRender="{ record }">
          <Descriptions :column="4" style="padding: 15px 0 0 20px">
            <DescriptionsItem label="预警服务">{{
              record.data.isOpenWarning == 1 ? '开启' : '关闭'
            }}</DescriptionsItem>
            <DescriptionsItem label="预警主题">{{
              record.data.subscribedTopicWarning
            }}</DescriptionsItem>
            <DescriptionsItem label="预警回复">{{
              record.data.ackTopicWarning
            }}</DescriptionsItem>
            <DescriptionsItem label="速报主题">{{
              record.data.subscribedTopicReport
            }}</DescriptionsItem>
            <DescriptionsItem label="速报回复">{{
              record.data.ackTopicReport
            }}</DescriptionsItem>
            <DescriptionsItem label="演练预警主题">{{
              record.data.isOpenDrillWarningTopic == 1 ? '开启' : '关闭'
            }}</DescriptionsItem>
            <DescriptionsItem label="演练主题订阅地址">{{
              record.data.subscribedTopicDrillWarning
            }}</DescriptionsItem>
            <DescriptionsItem label="license">{{
              record.data.license
            }}</DescriptionsItem>
            <DescriptionsItem label="owner">{{
              record.data.owner
            }}</DescriptionsItem>
            <DescriptionsItem label="type">{{
              record.data.type
            }}</DescriptionsItem>
            <DescriptionsItem label="协议地址">{{
              record.data.serverIp
            }}</DescriptionsItem>
            <DescriptionsItem label="注册接口">{{
              record.data.mqttRegisterUrl
            }}</DescriptionsItem>
            <DescriptionsItem label="授权接口">{{
              record.data.mqttAuthenticationUrl
            }}</DescriptionsItem>
            <DescriptionsItem label="Token接口">{{
              record.data.mqttConnectToken
            }}</DescriptionsItem>
          </Descriptions>
        </template>
      </ProTable>
    </Modal>
  </template>
</template>

<script setup lang="tsx">
import { computed, nextTick, ref, shallowRef } from 'vue';
import {
  Descriptions,
  DescriptionsItem,
  InputPassword,
  Modal,
  message,
} from 'ant-design-vue';
import { ProForm, ProFormProps } from '@/components/ProForm';
import { ItemProps } from '@/components/ProForm/interface';
import { ProTable, ProTableProps } from '@/components/ProTable/index';
import {
  authorizeMqtt,
  getMqttConfig_2,
  historyMqtt,
  mqttHistoryUpdate,
  registerMqtt,
  updateMqttConfig_2,
} from '@/api/device';
import FooterButtons from './FooterButtons.vue';

defineOptions({
  name: 'Mqtt',
});

interface Props {
  pageData: any;
  readonly?: any;
  fastConfig?: boolean;
}
const props = defineProps<Props>();
const loaded = ref(false);
const readonly = ref(props.readonly ?? true);
const formRef = shallowRef();
const formState = ref<Record<string, any>>({});
const column = 3;
const formColLayout = () => {
  const num = 24 / column;
  return { xs: num, sm: num, md: num, lg: num };
};
const formProps = computed<ProFormProps>(() => {
  return {
    labelCol: { span: 7 },
    wrapperCol: { span: 20 },
  };
});
const onValuesChange = (
  values: Record<string, any>,
  state: Record<string, any>,
) => {
  formState.value = {
    ...formState.value,
    ...state,
  };
};
const refresh = () => {
  loaded.value = false;
  nextTick(() => {
    loaded.value = true;
  });
};
const itemObj = (
  label: string,
  field: any,
  layout?: any,
  required: boolean = false,
  props?: any,
): ItemProps => {
  return {
    label,
    type: 'input',
    field,
    props: {
      placeholder: `请输入${label}`,
      allowClear: false,
      autocomplete: 'off',
      ...props,
    },
    rules: [{ required, message: `请输入${label}`, trigger: 'blur' }],
    ...layout,
  };
};
const itemRender = (title: string): ItemProps => {
  return {
    label: { title },
    type: 'input',
    field: 'h5',
    formItemRender() {
      return <h5 class='h5'>{title}</h5>;
    },
  };
};
const radioOptions = [
  { value: '0', label: '关闭' },
  { value: '1', label: '开启' },
];
const warnConnectTypeOptions = [
  { value: '0', label: '无' },
  { value: '1', label: '防篡改协议' },
];
const tamperResistantTypeOptions = [
  { value: '0', label: '无' },
  { value: '1', label: '国密SM2协议' },
  { value: '2', label: '防篡改协议' },
];
const isNewVersion = Number(props.pageData.protobufVersion) > 0;
const historyVisible = ref(false);

const items = computed<ProFormProps['items']>(() => [
  itemRender('服务配置'),
  {
    label: '预警服务',
    type: 'radio',
    field: ['serverConfig', 'isOpenWarning'],
    props: { options: radioOptions },
    rules: [{ required: true, message: '请选择预警服务', trigger: 'blur' }],
  },
  itemRender('MQTT主连配置'),
  itemObj('客户端ID', ['mainMqttConfig', 'mqttClientId']),
  itemObj('群组ID', ['mainMqttConfig', 'groupId']),
  itemObj('服务IP地址', ['mainMqttConfig', 'mqttIp']),
  itemObj('服务端口', ['mainMqttConfig', 'mqttPort'], undefined, true),
  itemObj('账号', ['mainMqttConfig', 'mqttAccount']),
  {
    label: '密码',
    type: 'input',
    field: ['mainMqttConfig', 'mqttPassword'],
    customRender(state) {
      return (
        <InputPassword
          v-model:value={state.mainMqttConfig.mqttPassword}
          placeholder='请输入密码'
          autocomplete='new-password'
        />
      );
    },
  },
  ...(isNewVersion
    ? [
        itemRender('MQTT备连配置'),
        {
          label: '启用备地址',
          type: 'radio',
          field: ['alternateMqttConfig', 'isOpenAlternateWarning'],
          props: { options: radioOptions },
          rules: [
            {
              required: true,
              message: '请选择是否启用备地址',
              trigger: 'blur',
            },
          ],
        } as ItemProps,
        itemObj('备服务IP地址', ['alternateMqttConfig', 'alternateMqttIp']),
        itemObj('备服务端口', ['alternateMqttConfig', 'alternateMqttPort']),
        itemObj(
          '超时时间',
          ['alternateMqttConfig', 'warnOverTime'],
          undefined,
          undefined,
          {
            addonAfter: '秒',
          },
        ),
      ]
    : []),
  itemRender('业务主题配置'),
  itemObj('预警主题', ['warnTopicConfig', 'subscribedTopicWarning']),
  itemObj('预警回复', ['warnTopicConfig', 'ackTopicWarning']),
  itemObj('速报主题', ['warnTopicConfig', 'subscribedTopicReport']),
  itemObj('速报回复', ['warnTopicConfig', 'ackTopicReport']),
  itemRender('演练主题配置'),
  {
    label: '演练预警主题',
    type: 'radio',
    field: ['drillTopicConfig', 'isOpenDrillWarningTopic'],
    props: { options: radioOptions },
    rules: [{ required: true, message: '请选择演练预警主题', trigger: 'blur' }],
  },
  itemObj(
    '演练主题订阅地址',
    ['drillTopicConfig', 'subscribedTopicDrillWarning'],
    {
      colProps: { span: 16 },
      labelCol: { span: 4 },
    },
  ),
  itemRender('标准配置'),
  itemObj('license', ['authConfig', 'license']),
  itemObj('owner', ['authConfig', 'owner']),
  itemObj('type', ['authConfig', 'type']),
  itemObj('协议地址', ['authConfig', 'serverIp']),
  itemObj('注册接口', ['authConfig', 'mqttRegisterUrl']),
  itemObj('授权接口', ['authConfig', 'mqttAuthenticationUrl']),
  itemObj('Token接口', ['authConfig', 'mqttConnectToken']),
  itemRender('防篡改协议参数'),
  {
    label: '连接协议类型',
    type: 'select',
    field: ['warnSafeConfig', 'warnConnectType'],
    props: { options: warnConnectTypeOptions },
    rules: [{ required: true, message: '请选择连接协议类型', trigger: 'blur' }],
  },
  {
    label: '验签协议类型',
    type: 'select',
    field: ['warnSafeConfig', 'tamperResistantType'],
    props: { options: tamperResistantTypeOptions },
    rules: [{ required: true, message: '请选择验签协议类型', trigger: 'blur' }],
  },
  itemObj('国密SM2公钥', ['warnSafeConfig', 'publicKey']),
  itemObj('校验服务地址', ['warnSafeConfig', 'cartesianConfig', 'serverUrl']),
  itemObj('介质云域名', ['warnSafeConfig', 'cartesianConfig', 'mckIp']),
  itemObj('介质云端口', ['warnSafeConfig', 'cartesianConfig', 'mckPort']),
  itemObj('介质云应用ID', ['warnSafeConfig', 'cartesianConfig', 'mckAppId']),
  itemObj('介质云Secret', [
    'warnSafeConfig',
    'cartesianConfig',
    'mckAppSecret',
  ]),
  itemObj('证书请求地址', ['warnSafeConfig', 'cartesianConfig', 'caDeviceId']),
  itemObj('证书设备ID', ['warnSafeConfig', 'cartesianConfig', 'caBaseUrl']),
  itemObj('证书应用ID', ['warnSafeConfig', 'cartesianConfig', 'caAppId']),
  itemObj('证书Secert', ['warnSafeConfig', 'cartesianConfig', 'caAppSecret']),
]);

props.pageData.mqttConfigsJson
  ? (() => {
      formState.value = JSON.parse(props.pageData.mqttConfigsJson);
      loaded.value = true;
    })()
  : getMqttConfig_2(props.pageData.code).then((res: any) => {
      formState.value = JSON.parse(res.data.paramsJson);
      loaded.value = true;
    });

const _updateMqttConfig_2 = (params: any) => {
  const code = props.pageData.code;
  const paramsJson = JSON.stringify(params);
  return updateMqttConfig_2({ paramsJson, code });
};
const _historyMqtt = async (params: any) => {
  params.code = props.pageData.code;
  const res: any = await historyMqtt(params);
  res.rows.forEach((item: any) => {
    if (typeof item.data == 'string') {
      item.data = JSON.parse(item.data);
    }
  });
  return res;
};
const MQTT_deploy = (record: any) => {
  Modal.confirm({
    title: '系统提示',
    centered: true,
    content: '确定是否下发该配置?下发后会覆盖设备当前配置',
    onOk: async () => {
      const res = await mqttHistoryUpdate(
        props.pageData.code + '/' + record.id,
      );
      formState.value = record.data;
      refresh();
      historyVisible.value = false;
      message.success(res.msg);
    },
  });
};
const expandedRowKeys: any = ref([]);
const handleExpand = (expanded: any, record: any) => {
  if (expanded) {
    expandedRowKeys.value = [record.id];
  } else {
    expandedRowKeys.value = [];
  }
};
const columns = computed<ProTableProps['columns']>(() => [
  {
    title: '时间',
    dataIndex: 'createTime',
    width: 120,
  },
  {
    title: '账号',
    dataIndex: ['data', 'mqttAccount'],
    width: 100,
  },
  {
    title: '客户端ID',
    dataIndex: ['data', 'mqttClientId'],
    width: 200,
  },
  {
    title: '群组ID',
    dataIndex: ['data', 'groupId'],
    width: 80,
  },
  {
    title: '服务IP地址',
    dataIndex: ['data', 'mqttIp'],
    width: 100,
  },
  {
    title: '服务端口',
    dataIndex: ['data', 'mqttPort'],
    width: 80,
  },
  {
    title: '密码',
    dataIndex: ['data', 'mqttPassword'],
    width: 100,
  },
  {
    title: '操作',
    dataIndex: 'operation',
    fixed: 'right',
    width: 60,
  },
]);

const handleRegister = async () => {
  const res: any = await registerMqtt({
    url: formState.value.serverIp + formState.value.mqttRegisterUrl,
    license: formState.value.license,
    owner: formState.value.owner,
    type: formState.value.type,
  });
  if (res.data.data) {
    if (res.data.data.Result.clientId) {
      formRef.value.setFiledValue(
        'mqttClientId',
        res.data.data.Result.clientId,
      );
      formRef.value.setFiledValue('groupId', res.data.data.Result.groupId);
      formRef.value.setFiledValue('mqttAccount', res.data.data.Result.uname);
      formRef.value.setFiledValue('mqttPassword', res.data.data.Result.pwd);
    } else {
      return res.data.data.Result.result
        ? message.error(res.data.data.Result.result)
        : message.error(res.data.data.Result);
    }
  } else {
    if (res.data.status.statusCode == 404) {
      return message.error('协议地址配置有误，请检查后再试');
    }
  }

  const _res: any = await authorizeMqtt({
    url: formState.value.serverIp + formState.value.mqttAuthenticationUrl,
    scope: 'EEW,EQR,ACK,EIR,EEW-DR',
    clientId: res.data.data.Result.clientId,
    pwd: res.data.data.Result.pwd,
    uname: res.data.data.Result.uname,
  });
  if (Array.isArray(_res.data.data.Result)) {
    message.success('注册成功');
    _res.data.data.Result.forEach((item: any) => {
      if (item.scope == 'EEW') {
        formRef.value.setFiledValue(
          'mqttIp',
          item.mqtthost.replace(/^(http|https):\/\//, ''),
        );
        formRef.value.setFiledValue('mqttPort', item.port);
        formRef.value.setFiledValue('subscribedTopicWarning', item.topic);
      } else if (item.scope == 'EQR') {
        formRef.value.setFiledValue('subscribedTopicReport', item.topic);
      } else if (item.scope == 'ACK') {
        formRef.value.setFiledValue('ackTopicWarning', item.topic);
      } else if (item.scope == 'EEW-DR') {
        formRef.value.setFiledValue('subscribedTopicDrillWarning', item.topic);
      }
    });
  } else {
    return message.error(_res.data.data.Result);
  }
};

defineExpose({
  async save() {
    const data = await formRef.value.validate();
    props.pageData.mqttConfigsJson = JSON.stringify(data);
  },
});
</script>
